<?php
declare (strict_types=1);

namespace app\common\model;

use addons\Target\facade\Target;
use think\facade\Cache;
use think\facade\Event;

class User extends Base
{
    protected $type = [
        'active_time' => 'timestamp',
    ];

    protected function assets(): object
    {
        return $this->hasOne(Assets::class, 'uid');
    }

    protected function level(): object
    {
        return $this->hasOne(Level::class, 'id', 'level_id');
    }

    protected function getPhotoAttr($value): string
    {
        return $value ?: Cache::get('system')['default_photo'];
    }

    protected function getParentInfoAttr($value, $data): string
    {
        $title = '-';
        if ($data['parent_id']) {
            $info = parent::where(['id' => $data['parent_id']])->find();
            $title = $info->code . '-' . $info->nickname . '-' . $info->mobile;
        }

        return $title;
    }

    public static function _save($param, $logs): array
    {
        parent::startTrans();
        try {
            if (!empty($param['id'])) {
                $msg = '操作成功';
                $original = parent::where(['id' => $param['id']])->find();
                if (empty($original)) {
                    throw new \Exception('记录不存在，请检查');
                }
                $model = parent::update($param);
                $logs['original'] = $original;
                $logs['operation'] = 'save';
                if ($logs['writeLog']) {
                    $logs['model'] = $model;
                    Event::trigger('Logs', $logs);
                }
            } else {
                $msg = '注册成功';
                $parent = parent::where(['code' => $param['parent_code'], 'is_active' => 2])->find();
                if (empty($parent)) {
                    throw new \Exception('邀请码不存在或未激活');
                }
                $param['parent_id'] = $parent->id;
                $param['code'] = generate();
                $param['mobile'] = trim($param['mobile']);
                $param['password'] = !empty($param['password']) ? md5($param['password']) : md5('111111');
                $param['pay_password'] = !empty($param['pay_password']) ? md5($param['pay_password']) : md5('222222');
                parent::create($param);
            }

            parent::commit();
        } catch (\Exception $e) {
            parent::rollback();

            return ['code' => -1, 'msg' => $e->getMessage()];
        }

        return ['code' => 1, 'msg' => $msg, 'url' => url('login/index')->build()];
    }

    public static function onAfterInsert($user): void
    {
        $user->assets()->save(['uid' => $user->id]);
        if ($user->parent_id) {
            Relation::generate($user->id, $user->code, $user->parent_id, $user->parent_code);
        }
    }

    public static function recharge($param, $admin): array
    {
        parent::startTrans();
        try {
            $user = parent::find($param['id']);
            if ($user->isEmpty()) {
                throw new \Exception('未查询到相关会员');
            }
            $account = get_pay_way($param['account']);
            if ($param['mode'] == 1) {
                Target::Account()->basics($param['id'], $param['account'], $param['amount'], '后台充值', '+')
                    ->setOperator($admin->admin_name)->setMsg($param['remarks'])->createRecharge();
                $logs = '后台充值【' . $account . '】金额【' . $param['amount'] . '】会员【' . $user->code . '】';
            } else {
                Target::Account()->basics($param['id'], $param['account'], $param['amount'], '后台扣除', '-')
                    ->setOperator($admin->admin_name)->setMsg($param['remarks'])->createRecharge();
                $logs = '后台扣除【' . $account . '】金额【' . $param['amount'] . '】会员【' . $user->code . '】';
            }
            Logs::adds($logs, $admin['id'], $admin['admin_name']);

            parent::commit();
        } catch (\Exception $e) {
            parent::rollback();

            return ['code' => -1, 'msg' => $e->getMessage()];
        }

        return ['code' => 1, 'msg' => '操作成功'];
    }

    /**
     * 检测用户收款方式
     */
    public static function checkReceipt($user): bool
    {
        // 微信
        if (empty($user->wechat_name) && empty($user->wechat_image)
            && empty($user->alipay_name) && empty($user->alipay_image)
            && empty($user->bank_name) && empty($user->bank_number)) {

            return false;
        }

        return true;
    }

    /**
     * 获取大小区业绩
     */
    public static function inviteSizeConsume($uid): array
    {
        $min_total = 0;
        $max_total = 0;
        $list = parent::where(['parent_id' => $uid])->order('total desc')
            ->column('my_total+team_total as total');
        if ($list) {
            $max_total = array_shift($list);
            if ($list) {
                $min_total = array_sum($list);
            }
        }

        return ['min_total' => $min_total, 'max_total' => $max_total];
    }

    /**
     * 判断一个会员是否在上级会员小市场
     */
    public static function maximumUser($uid, $relation_id): int
    {
        $count = 0;
        $list = parent::where(['parent_id' => $uid])->order('total desc')
            ->column('id,my_total+team_total as total');
        if ($list) {
            array_shift($list);
            if ($list) {
                $childs = array_column($list, 'id');
                if (in_array($relation_id, $childs)) {
                    $count = 1;
                } else {
                    $count = Relation::whereIn('uid', $childs)->where(['new_uid' => $relation_id])->count();
                }
            }
        }

        return $count;
    }

    /**
     * 获取团队每条线上符合条件的条数
     */
    public static function getMarketCount($uid, $field, $level_id, $gs): int
    {
        $list = parent::where(['parent_id' => $uid])->column('id');
        $market = 0;
        foreach ($list as $v) {
            $ids = Relation::where(['uid' => $v])->column('new_uid');
            $ids[] = $v;
            $count = parent::whereIn('id', $ids)->where($field, '>=', $level_id)->count();
            if ($count >= $gs) {
                $market++;
            }
        }

        return $market;
    }
}